/*
 * @Author       : wfl
 * @LastEditors  : wfl
 * @description  :
 * @updateInfo   :
 * @Date         : 2023-10-31 11:22:32
 * @LastEditTime : 2024-01-19 09:45:08
 */
import { ScreenEntity } from './../entity/screen';
import { ComponentEntity } from '../../coms/entity/component';
import { TemplateEntity } from '../../template/entity/template';
import { TemplateComponentEntity } from '../../template/entity/templateComponent';
import { FilterEntity } from '../../filter/entity/filter';
import { TemplateFilterEntity } from '../../template/entity/templateFilter';
import { Provide } from '@midwayjs/decorator';
import { BaseService } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Like, Repository } from 'typeorm';
import { buildShortUUID } from '../../../comm/uuid';
const os = require('os');

@Provide()
export class ScreenService extends BaseService {
  @InjectEntityModel(ScreenEntity)
  screenEntity: Repository<ScreenEntity>;

  @InjectEntityModel(ComponentEntity)
  componentEntity: Repository<ComponentEntity>;

  @InjectEntityModel(FilterEntity)
  filterEntity: Repository<FilterEntity>;

  @InjectEntityModel(TemplateEntity)
  templateEntity: Repository<TemplateEntity>;

  @InjectEntityModel(TemplateComponentEntity)
  templateComponentEntity: Repository<TemplateComponentEntity>;

  @InjectEntityModel(TemplateFilterEntity)
  templateFilterEntity: Repository<TemplateFilterEntity>;

  async queryById(id: number) {
    const result = await this.screenEntity.findOneBy({ id });
    return result
      ? {
          ...result,
          pages: JSON.parse(result.pages),
          dialogs: JSON.parse(result.dialogs),
          variables: JSON.parse(result.variables),
          host: JSON.parse(result.host),
          events: JSON.parse(result.events),
          iframe: JSON.parse(result.iframe),
          styleFilterParams: JSON.parse(result.styleFilterParams),
        }
      : null;
  }

  async getScreenWithChildren(param) {
    const res = await this.screenEntity.find({
      where: {
        groupId: Like(`${param.id}%`),
        name: Like(`${param?.name || ''}%`),
      },
      order: {
        [param.order]: 'DESC',
      },
    });
    return Array.isArray(res) ? res : [res];
  }

  /**
   * Copies the screen with the specified ID.
   *
   * @param {string} id - The ID of the screen to be copied.
   * @return {object} - An object containing the result of the copy operation.
   *   - `msg` (string): A message indicating the result of the copy operation.
   *   - `data` (null): No additional data is returned.
   */
  async copyScreen(id: string) {
    // eslint-disable-next-line no-useless-catch
    try {
      const res = await this.screenEntity.findOneBy({ id: id as any });
      // copy大屏
      const newScreen = await this.screenEntity.save({
        ...res,
        id: null,
        name: `${res.name}-副本`,
      });
      const pages = JSON.parse(newScreen.pages);
      // coms组件
      const coms = await this.componentEntity.findBy({ screenId: id });
      for (const com of coms) {
        const newId = `${com.id.split('_')[0]}_${buildShortUUID()}`;
        pages.forEach(page => {
          page.children = page.children.map(cid =>
            cid === com.id ? newId : cid
          );
        });
        const d = await this.componentEntity.save({
          ...com,
          id: newId,
          screenId: newScreen.id,
        });
      }
      await this.screenEntity.update({ id: newScreen.id }, {
        ...newScreen,
        pages: JSON.stringify(pages),
      } as any);
      // 过滤器 filters
      const filters = await this.filterEntity.findBy({ screenId: id });
      for (const filter of filters) {
        const d = await this.filterEntity.save({
          ...filter,
          id: null,
          screenId: newScreen.id,
        });
      }
      return {
        msg: '复制成功',
        data: null,
      };
    } catch (error) {
      console.error('error: ', error);
      return {
        msg: '复制失败',
        data: null,
      };
    }
    return {
      msg: '复制失败',
      data: null,
    };
  }

  async renameScreen(id: any, name: string) {
    const screen = await this.screenEntity.findOneBy({ id: id as any });
    await this.screenEntity.update(
      { id },
      {
        ...screen,
        name,
      }
    );
    return {
      msg: '重命名成功',
      data: null,
    };
  }

  async publishInfo(id: any) {
    let shareUrl = '';
    shareUrl = `http://${this.baseCtx.host}/share/#/screen/${id}`;

    const screen = await this.screenEntity.findOneBy({ id });
    await this.screenEntity.update(
      { id },
      {
        ...screen,
        // shared: true,
        shareUrl,
        shareTime: new Date(),
      }
    );
    return {
      shareUrl,
      shared: screen.shared,
      password: screen.sharePassword,
      shareTime: new Date(),
    };
  }

  async publishScreen(screen) {
    const re_screen = await this.screenEntity.findOneBy({ id: screen.id });
    const res = await this.screenEntity.update(
      { id: screen.id },
      {
        ...re_screen,
        shared: screen.shared,
        shareUrl: screen.shareUrl,
        sharePassword: screen.sharePassword,
      }
    );
    return res;
  }

  async templateScreen(data) {
    try {
      const res = await this.templateEntity.findOneBy({
        id: data.templateId as any,
      });
      // copy大屏
      const newScreen = await this.screenEntity.save({
        ...JSON.parse(res?.config || '{}'),
        groupId: data.groupId,
        shared: false,
        shareUrl: '',
        sharePassword: '',
        id: null,
        name: data.name,
      });
      const pages = JSON.parse(newScreen.pages);
      // coms组件
      const coms = await this.templateComponentEntity.findBy({
        templateId: data.templateId,
      });
      for (const com of coms) {
        const newId = `${com.id.split('_')[0]}_${buildShortUUID()}`;
        pages.forEach(page => {
          page.children = page.children.map(cid =>
            cid === com.id ? newId : cid
          );
        });
        const d = await this.componentEntity.save({
          ...com,
          id: newId,
          screenId: newScreen.id,
        });
      }
      // 更新组件id
      await this.screenEntity.update({ id: newScreen.id }, {
        ...newScreen,
        pages: JSON.stringify(pages),
      } as any);
      // 过滤器 filters
      const filters = await this.templateFilterEntity.findBy({
        templateId: data.templateId,
      });
      for (const filter of filters) {
        const d = await this.filterEntity.save({
          ...filter,
          id: null,
          screenId: newScreen.id,
        });
      }
      return coms && filters ? newScreen : false;
    } catch (error) {
      console.error('error: ', error);
      return false;
    }
  }
}
